home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #1 / Amiga Plus CD - 2000 - No. 1.iso / Tools / Dev / Sas-PPC / c_ppc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-03  |  6.5 KB  |  275 lines

  1. int _start(char *);
  2. extern struct WBStartup *_WBenchMsg;
  3. _main(char *line, struct WBStartup *msg)
  4. {
  5.    if (line == 0L) _WBenchMsg = msg;
  6.    return _start(line);
  7. }
  8.  
  9. /***
  10. *
  11. *          Copyright © 1997 SAS Institute, Inc.
  12. *
  13. * name             __main - process command line, open files, and call main()
  14. *
  15. * synopsis         __main(line);
  16. *                  char *line;     ptr to command line that caused execution
  17. *
  18. * description      This function performs the standard pre-processing for
  19. *                  the main module of a C program.  It accepts a command
  20. *                  line of the form
  21. *
  22. *                       pgmname arg1 arg2 ...
  23. *
  24. *                  and builds a list of pointers to each argument.  The first
  25. *                  pointer is to the program name.  
  26. *
  27. ***/
  28.  
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <stdlib.h>
  32. #include <setjmp.h>
  33. #include <constructor.h>
  34. #include <workbench/startup.h>
  35. #include <libraries/dos.h>
  36. #include <libraries/dosextens.h>
  37. #include <exec/memory.h>
  38. #include <powerup/gcclib/powerup_protos.h>
  39. #include <proto/exec.h>
  40. #include <proto/dos.h>
  41.  
  42. #define QUOTE       '"'
  43. #define ESCAPE '*'
  44. #define ESC '\x1b'
  45. #define NL '\n'
  46.  
  47. #define isspace(c)      ((c == ' ')||(c == '\t') || (c == '\n'))
  48.  
  49. struct CTDT {
  50.     long priority;
  51.     int (*fp)(void);
  52. };
  53.  
  54. static struct CTDT *sort_ctdt(struct CTDT **last);
  55.  
  56. static jmp_buf __exit_jmpbuf;
  57. static int __exit_return;
  58. struct DosLibrary *DOSBase;
  59. struct ExecBase *SysBase;
  60.  
  61. struct WBStartup *_WBenchMsg;
  62. char *_ProgramName = "";
  63. int main(int, void *);
  64. long __PPC_SHELL_START;   /* special symbol so P5 patch knows it's ok to load this */
  65.  
  66. BPTR __curdir;
  67.  
  68. static int argc;                   /* arg count */
  69. static char **targv, **argv;       /* arg pointers */
  70.  
  71. int _start(char *line)
  72. {
  73.     char *argbuf;
  74.     int ret;
  75.     int i;
  76.     struct CTDT *ctdt, *last_ctdt;
  77.  
  78.     SysBase = *(struct ExecBase **)4;
  79.     DOSBase = (void *)OpenLibrary("dos.library",0);
  80.     if (DOSBase == NULL) return 20;
  81.  
  82.  
  83.     /* grab the current directory */
  84.     __curdir = CurrentDir(0);
  85.     CurrentDir(__curdir);
  86.  
  87. /***
  88. *     First count the number of arguments
  89. ***/
  90.    argbuf = line;
  91.  
  92.    if (line == NULL) argc = 0;
  93.    else for (argc = 0; ; argc++)
  94.    {
  95.         while (isspace(*line))  line++;
  96.         if (*line == '\0')      break;
  97.         if (*line == QUOTE)
  98.         {
  99.             line++;
  100.             while (*line != QUOTE && *line != 0)
  101.             {
  102.                if (*line == ESCAPE)
  103.                {
  104.                   line++;
  105.                   if (*line == 0) break;
  106.                }
  107.                line++;
  108.             }
  109.             if (*line) line++;
  110.         }
  111.         else            /* non-quoted arg */
  112.         {       
  113.             while ((*line != '\0') && (!isspace(*line))) line++;
  114.         }
  115.    }
  116.  
  117.    if (argc)
  118.    {
  119.       argv = PPCAllocMem((argc+1) * sizeof(char *), MEMF_CLEAR);
  120.       if (argv == NULL)
  121.          return 20;
  122.          
  123.       /***
  124.       *     Build argument pointer list
  125.       ***/
  126.       i = 0;
  127.       line = argbuf;
  128.       while (1)
  129.       {
  130.            while (isspace(*line))  line++;
  131.            if (*line == '\0')      break;
  132.            if (*line == QUOTE)
  133.            {
  134.                argbuf = argv[i++] = ++line;  /* ptr inside quoted string */
  135.                while (*line != QUOTE && *line != 0)
  136.                {
  137.                   if (*line == ESCAPE)
  138.                   {
  139.                      line++;
  140.                      switch (*line)
  141.                      {
  142.                         case '\0':
  143.                            *argbuf = 0;
  144.                            goto linedone;
  145.                         case 'E':
  146.                            *argbuf++ = ESC;
  147.                            break;
  148.                         case 'N':
  149.                            *argbuf++ = NL;
  150.                            break;
  151.                         default:
  152.                            *argbuf++ = *line;
  153.                      }
  154.                      line++;
  155.                   }
  156.                   else
  157.                   {
  158.                     *argbuf++ = *line++;
  159.                   }
  160.                }
  161.                if (*line) line++;
  162.                *argbuf++ = '\0'; /* terminate arg */
  163.            }
  164.            else            /* non-quoted arg */
  165.            {       
  166.                argv[i++] = line;
  167.                while ((*line != '\0') && (!isspace(*line))) line++;
  168.                if (*line == '\0')  break;
  169.                else                *line++ = '\0';  /* terminate arg */
  170.            }
  171.       }  /* while */
  172.       _ProgramName = argv[0];
  173.    }
  174. linedone:
  175.  
  176.     targv = (argc == 0) ? (char **) _WBenchMsg : (char **) &argv[0];
  177.  
  178.  
  179.    /* LD merges all the contructors and destructors together in random */
  180.    /* order. All destructors are negated, and then an unsigned sort  */
  181.    /* is preformed, so the constructors come out first, followed by */
  182.    /* the destructors in reverse order */
  183.    ctdt = sort_ctdt(&last_ctdt);
  184.  
  185.    while (ctdt < last_ctdt && ctdt->priority >= 0)
  186.    {
  187.        if (ctdt->fp() != 0)
  188.        {
  189.            /* skip the remaining constructors */
  190.            while (ctdt < last_ctdt && ctdt->priority >= 0)
  191.               ctdt++;
  192.            ret = 20;
  193.            goto cleanup;
  194.        }
  195.        ctdt++;
  196.    }
  197.  
  198.  
  199.  
  200.  
  201. /***
  202. *     Call user's main program
  203. ***/
  204.  
  205. /* We I get setjmp ported, I'll do a setjmp here, then */
  206. /* have exit() do a longjmp back, and return            */
  207. if ((ret = setjmp(__exit_jmpbuf)) == 0)
  208.    {
  209.        ret = main(argc, targv);                /* call main function */
  210.        exit(ret); 
  211.    }
  212. else ret = __exit_return;
  213.  
  214.  
  215. cleanup:
  216.  
  217.    
  218.    /* call destructors here */
  219.    while (ctdt < last_ctdt)
  220.    {
  221.       ctdt->fp();
  222.       ctdt++;
  223.    }
  224.  
  225.    if (argc && argv)
  226.        PPCFreeMem(argv, (argc+1) * sizeof(char *));
  227.  
  228.    CloseLibrary((void *)DOSBase);
  229.  
  230.    return ret;
  231. }
  232.  
  233.  
  234. void _XCEXIT(long d0)
  235. {
  236.     /* this will longjmp back to main when longjmp is ready */
  237.     __exit_return = d0;
  238.     longjmp(__exit_jmpbuf, 1);
  239. }
  240.  
  241.  
  242.  
  243. int _STI_0_dummy(void)
  244. {
  245.     /* dummy constructor there is something in the modules .ctdt section */
  246.     return 0;
  247. }
  248.  
  249. struct CTDT *get_last_ctdt(void);
  250.  
  251. static int comp_ctdt(struct CTDT *a, struct CTDT *b)
  252. {
  253.     if (a->priority == b->priority) return 0;
  254.     if ((unsigned long)a->priority < (unsigned long) b->priority) return -1;
  255.     return 1;    
  256. }
  257.  
  258. static struct CTDT *sort_ctdt(struct CTDT **last)
  259. {
  260.     extern void *__builtin_getsectionaddr(int);
  261.     struct CTDT *ctdt;
  262.     struct CTDT *last_ctdt;
  263.     
  264.     ctdt = __builtin_getsectionaddr(4);  /* the ctdt section is pointed to by sym 4 */;
  265.  
  266.     last_ctdt = get_last_ctdt();         /* from end.o */
  267.     
  268.     qsort(ctdt, last_ctdt - ctdt, sizeof(*ctdt), comp_ctdt);
  269.     
  270.     *last = last_ctdt;
  271.     
  272.     return ctdt;
  273. }
  274.     
  275.